package cn.liyiming.bbs.config.web;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import cn.liyiming.bbs.core.shiro.DbRealm;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * 配置Shiro相关组件
 */
@Configuration
public class ShiroConfig {

    /**
     * 加盐参数
     */
    public final static String hashAlgorithmName = "MD5";
    /**
     * 循环次数
     */
    public final static int hashIterations = 1024;

    //配置凭证匹配器（指定加密算法以及加密次数）
    @Bean
    public CredentialsMatcher credentialsMatcher() {
        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //加密算法
        credentialsMatcher.setHashAlgorithmName(hashAlgorithmName);
        //加密次数
        credentialsMatcher.setHashIterations(hashIterations);
        return credentialsMatcher;
    }

    //配置自定义realm
    @Bean
    public DbRealm dbRealm() {
        DbRealm dbRealm = new DbRealm();
        dbRealm.setCredentialsMatcher(credentialsMatcher());
        return dbRealm;
    }

    //配置Securitymanager
    @Bean
    public DefaultWebSecurityManager securityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(dbRealm());
        return securityManager;
    }

    //开启Shiro注解功能 （因为Shiro注解需要依赖AOP）
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();
        defaultAAP.setProxyTargetClass(true);
        return defaultAAP;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
        return authorizationAttributeSourceAdvisor;
    }

    //配置shiro过滤器
    //需要指定哪些路径需要被shiro过滤（需要指定具备什么角色才能访问） 哪些不需要
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager());
        Map<String, String> map = new HashMap<>();
        //登出

        map.put("/user/login", "anon");
        map.put("/user/reg", "anon");
        map.put("/user/add", "anon");
        map.put("/user/forget", "anon");
        map.put("/user/verifyLogin", "anon");
        map.put("/index", "anon");
        map.put("/catalog", "anon");
        //静态资源放行
        map.put("/res/**", "anon");
        //登录
        map.put("/logout", "logout");
        //对所有用户认证
        map.put("/**", "authc");
        shiroFilterFactoryBean.setLoginUrl("/index");
        //shiroFilterFactoryBean.setLoginUrl("/user/login");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    //整合thymeleaf
    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect() {
        return new ShiroDialect();
    }


}
